
from demo import models
from demo import serializers

from rest_framework.viewsets import ViewSet, GenericViewSet, ReadOnlyModelViewSet
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticated

"""
但是我们还是发现，列表视图和详情视图还是不能写在同一个类中，因为列表视图的get和详情视图的get是重复的
为了写在同一个类中，有了视图集：
1 ViewSet 继承 了APIView
2 GenericViewSet 继承了 GenericAPIView

不过这些视图集重写了标准http的method，转换为：
list() 提供一组数据
retrieve() 提供单个数据
create() 创建数据
update() 保存数据
destroy() 删除数据
"""

# 这里是继承了ViewSet，也就是说这个类中的方法必须自己写序列化
class BookViewSet(ViewSet):
    def list(self, request):
        book = models.Book.objects.all()
        s = serializers.DrfBookSerializer(book, many=True)
        return Response(s.data)

    def create(self, request):
        pass

    def retrieve(self, request, pk):
        try:
            book = models.Book.objects.get(id=pk)
        except models.Book.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        s = serializers.DrfBookSerializer(book)
        return Response(s.data)

    def update(self, request, pk):
        pass

    def destroy(self, request, pk):
        pass

# 这里是继承了GenericViewSet，也就是说这个类中的方法不用写序列化。
class BookGenericViewSet(GenericViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializers.DrfBookSerializer

    def list(self, request):
        req = self.get_queryset()
        s = self.get_serializer(req, many=True)
        return Response(s.data)

    def retrieve(self, request, pk):
        req = self.get_object()
        s = self.get_serializer(req)
        return Response(s.data)

"""
当然还有更简单的，使用多继承
注意：路由中需要把标准HTTP Method转换成DRF重写的方法。
"""
class BookEndGenericViewSet(ListCreateAPIView, RetrieveUpdateDestroyAPIView, GenericViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializers.DrfBookSerializer

    # 认证和授权，认证已经是全局认证，必须配置权限才能触发认证，不然就是allowany
    permission_classes = (IsAuthenticated,)

    # 额外功能
    # 列表视图自定义
    def lastbook(self, request):
        # 获取最后一本书
        req = models.Book.objects.latest('id')
        s = self.get_serializer(req)
        return Response(s.data)

    # 详情视图自定义
    def editbook(self, request, pk):
        book = self.get_object()
        book.price = request.data.get('price')
        book.save()
        serializer = self.get_serializer(book)
        return Response(serializer.data)


class BookReadViewSet(ReadOnlyModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializers.DrfBookSerializer